package com.keson.blue;
import android.app.usage.StorageStatsManager;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.os.Build;
import android.os.storage.StorageManager;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Locale;
import java.util.UUID;

public class DeviceControlUtil {
    private static boolean screenOpen = true;
    private static Context context;
    private static AudioManager am;
    private static SimpleDateFormat sdf = new SimpleDateFormat("MMddHHmmyyyy.ss");

    public static void init(Context context) {
        if (DeviceControlUtil.context == null) {
            DeviceControlUtil.context = context;
            am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
        }
    }

    public static void reboot() {
        if(Build.MODEL.indexOf("100c")>-1){
            execRootCmd("reboot");
        }else{
            Intent i = new Intent("android.intent.action.REBOOT");
            // 立即重启：1
            i.putExtra("nowait", 1);
            // 重启次数：1
            i.putExtra("interval", 1);
            // 出现弹窗：1
            i.putExtra("window", 0);
            context.startActivity(i);
        }
    }

    public static void shutDown() {
        if(Build.MODEL.indexOf("100c")>-1){
            Intent intent = new Intent("com.temolin.hardware.shutdown");
            context.sendBroadcast(intent);
        }else{
            Intent i = new Intent("android.intent.action.ACTION_REQUEST_SHUTDOWN");
            // 是否弹出提示框
            i.putExtra("android.intent.extra.KEY_CONFIRM", false);
            context.startActivity(i);
        }
    }

    /**
     * 执行命令并且输出结果
     */
    public static String execRootCmd(String cmd) {
        String result = "";
        DataOutputStream dos = null;
        DataInputStream dis = null;

        try {
            Process p = Runtime.getRuntime().exec("su");
            dos = new DataOutputStream(p.getOutputStream());
            dis = new DataInputStream(p.getInputStream());

//            Log.i(TAG, cmd);
            dos.writeBytes(cmd + "\n");
            dos.flush();
            dos.writeBytes("exit\n");
            dos.flush();
            String line = null;
            while ((line = dis.readLine()) != null) {
//                Log.d("result", line);
                result += line + "\n";
            }
            p.waitFor();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (dos != null) {
                try {
                    dos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (dis != null) {
                try {
                    dis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }

    public static Storage getAllStorageSize(){
        StorageManager storageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
        Storage storage = new Storage();
        try {
            Method getVolumes = StorageManager.class.getDeclaredMethod("getVolumes");//6.0
            List<Object> getVolumeInfo = (List<Object>) getVolumes.invoke(storageManager);
            long total = 0L, used = 0L;

            for (Object obj : getVolumeInfo) {

                Field getType = obj.getClass().getField("type");
                int type = getType.getInt(obj);

//                System.out.println("type: " + type);
                if (type == 1) {//TYPE_PRIVATE

                    long totalSize = 0L;

                    //获取内置内存总大小
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {//8.0也可以不做这个判断
                        Method getFsUuid = obj.getClass().getDeclaredMethod("getFsUuid");
                        String fsUuid = (String) getFsUuid.invoke(obj);
                        try {
                            UUID id;
                            if (fsUuid == null) {
                                id = StorageManager.UUID_DEFAULT;
                            } else {
                                id = UUID.fromString(fsUuid);
                            }
                            StorageStatsManager stats = context.getSystemService(StorageStatsManager.class);
                            totalSize = stats.getTotalBytes(id);
                        } catch (NoSuchFieldError | NoClassDefFoundError | NullPointerException | IOException e) {
                            e.printStackTrace();
                            totalSize = -1;
                        }
                    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {//7.1.1
                        //5.0 6.0 7.0没有
                        Method getPrimaryStorageSize = StorageManager.class.getMethod("getPrimaryStorageSize");
                        totalSize = (long) getPrimaryStorageSize.invoke(storageManager);
                    }
                    long systemSize = 0L;
                    Method isMountedReadable = obj.getClass().getDeclaredMethod("isMountedReadable");
                    boolean readable = (boolean) isMountedReadable.invoke(obj);
                    if (readable) {
                        Method file = obj.getClass().getDeclaredMethod("getPath");
                        File f = (File) file.invoke(obj);

                        if (totalSize == 0) {
                            totalSize = f.getTotalSpace();
                        }
//                        String _msg = "剩余总内存：" + getUnit(f.getTotalSpace(), 1000) + "\n可用内存：" + getUnit(f.getFreeSpace(), 1000) + "\n已用内存：" + getUnit(f.getTotalSpace() - f.getFreeSpace(), 1000);
//                        System.out.println(_msg);
                        systemSize = totalSize - f.getTotalSpace();
                        used += totalSize - f.getFreeSpace();
                        total += totalSize;
                    }
//                    System.out.println("totalSize = " + getUnit(totalSize, 1000) + " ,used(with system) = " + getUnit(used, 1000) + " ,free = " + getUnit(totalSize - used, 1000));
                    storage.setInternalStorageTotal(totalSize);
                    storage.setInternalStorageUsed(used);
                    storage.setInternalStorageAvailable(totalSize - used);
                    storage.setInternalStorageAvailablePercent(storage.getInternalStorageAvailable()/totalSize);
                } else if (type == 0) {//TYPE_PUBLIC
                    //外置存储
                    Method isMountedReadable = obj.getClass().getDeclaredMethod("isMountedReadable");
                    boolean readable = (boolean) isMountedReadable.invoke(obj);
                    if (readable) {
                        Method file = obj.getClass().getDeclaredMethod("getPath");
                        File f = (File) file.invoke(obj);
                        used += f.getTotalSpace() - f.getFreeSpace();
                        total += f.getTotalSpace();

                        storage.setExternalStorageTotal(f.getTotalSpace());
                        storage.setExternalStorageUsed(f.getTotalSpace() - f.getFreeSpace());
                        storage.setExternalStorageAvailable(f.getFreeSpace());
                        storage.setExternalStorageAvailablePercent(storage.getExternalStorageAvailable()/f.getTotalSpace());
                    }
                } else if (type == 2) {//TYPE_EMULATED

                }
            }
//            System.out.println("总内存 total = " + getUnit(total, 1000) + " ,已用 used(with system) = " + getUnit(used, 1000)+ "\n可用 available = " + getUnit(total - used, 1000));
            storage.setAllStorageTotal(total);
            storage.setAllStorageUsed(used);
            storage.setAllStorageAvailable(total - used);
            storage.setAllStorageAvailablePercent(storage.getAllStorageAvailable()/total);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return storage;
    }

    private static String[] units = {"B", "KB", "MB", "GB", "TB"};
    private static String getUnit(float size, int unit) {
        int index = 0;
        while (size > unit && index < 4) {
            size = size / unit;
            index++;
        }
        return String.format(Locale.getDefault(), " %.2f %s", size, units[index]);
    }

    public static class Storage{
        private  float internalStorageTotal;//内置存储总量
        private  float internalStorageAvailable;//内置存储可用
        private  float internalStorageUsed;//内置存储已用
        private  float internalStorageAvailablePercent ;//内置存储可用百分比

        private  float externalStorageTotal;//扩展存储总量
        private  float externalStorageAvailable;//扩展存储可用
        private  float externalStorageUsed;//扩展存储已用
        private  float externalStorageAvailablePercent;//内置存储可用百分比

        private  float allStorageTotal;//总量
        private  float allStorageAvailable;//总可用
        private  float allStorageUsed;//总已用
        private  float allStorageAvailablePercent;//内置存储可用百分比

        public String getInternalStorageTotalString() {
            return getUnit(internalStorageTotal, 1000);
        }

        public String getInternalStorageAvailableString() {
            return getUnit(internalStorageAvailable, 1000);
        }

        public String getInternalStorageUsedString() {
            return getUnit(internalStorageUsed, 1000);
        }

        public String getInternalStorageAvailablePercentString() {
            return String.format("%.2f", internalStorageAvailablePercent*100,"%");
        }

        public String getExternalStorageTotalString() {
            return getUnit(externalStorageTotal, 1000);
        }

        public String getExternalStorageAvailableString() {
            return getUnit(externalStorageAvailable, 1000);
        }

        public String getExternalStorageUsedString() {
            return getUnit(externalStorageUsed, 1000);
        }

        public String getExternalStorageAvailablePercentString() {
            return String.format("%.2f", externalStorageAvailablePercent*100,"%");
        }

        public String getAllStorageTotalString() {
            return getUnit(allStorageTotal, 1000);
        }

        public String getAllStorageAvailableString() {
            return getUnit(allStorageAvailable, 1000);
        }

        public String getAllStorageUsedString() {
            return getUnit(allStorageUsed, 1000);
        }

        public String getAllStorageAvailablePercentString() {
            return String.format("%.2f", allStorageAvailablePercent*100,"%");
        }

        public float getInternalStorageTotal() {
            return internalStorageTotal;
        }

        public void setInternalStorageTotal(float internalStorageTotal) {
            this.internalStorageTotal = internalStorageTotal;
        }

        public float getInternalStorageAvailable() {
            return internalStorageAvailable;
        }

        public void setInternalStorageAvailable(float internalStorageAvailable) {
            this.internalStorageAvailable = internalStorageAvailable;
        }

        public float getInternalStorageUsed() {
            return internalStorageUsed;
        }

        public void setInternalStorageUsed(float internalStorageUsed) {
            this.internalStorageUsed = internalStorageUsed;
        }

        public float getInternalStorageAvailablePercent() {
            return internalStorageAvailablePercent;
        }

        public void setInternalStorageAvailablePercent(float internalStorageAvailablePercent) {
            this.internalStorageAvailablePercent = internalStorageAvailablePercent;
        }

        public float getExternalStorageTotal() {
            return externalStorageTotal;
        }

        public void setExternalStorageTotal(float externalStorageTotal) {
            this.externalStorageTotal = externalStorageTotal;
        }

        public float getExternalStorageAvailable() {
            return externalStorageAvailable;
        }

        public void setExternalStorageAvailable(float externalStorageAvailable) {
            this.externalStorageAvailable = externalStorageAvailable;
        }

        public float getExternalStorageUsed() {
            return externalStorageUsed;
        }

        public void setExternalStorageUsed(float externalStorageUsed) {
            this.externalStorageUsed = externalStorageUsed;
        }

        public float getExternalStorageAvailablePercent() {
            return externalStorageAvailablePercent;
        }

        public void setExternalStorageAvailablePercent(float externalStorageAvailablePercent) {
            this.externalStorageAvailablePercent = externalStorageAvailablePercent;
        }

        public float getAllStorageTotal() {
            return allStorageTotal;
        }

        public void setAllStorageTotal(float allStorageTotal) {
            this.allStorageTotal = allStorageTotal;
        }

        public float getAllStorageAvailable() {
            return allStorageAvailable;
        }

        public void setAllStorageAvailable(float allStorageAvailable) {
            this.allStorageAvailable = allStorageAvailable;
        }

        public float getAllStorageUsed() {
            return allStorageUsed;
        }

        public void setAllStorageUsed(float allStorageUsed) {
            this.allStorageUsed = allStorageUsed;
        }

        public float getAllStorageAvailablePercent() {
            return allStorageAvailablePercent;
        }

        public void setAllStorageAvailablePercent(float allStorageAvailablePercent) {
            this.allStorageAvailablePercent = allStorageAvailablePercent;
        }
    }
}